﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;

namespace NFinal.Middleware.UnZip
{
    public delegate Task InvokeDelegate<TContext>(TContext context);
    public class UnZipMiddleware<TContext>
    {
        private string defaultUrl;
        private readonly InvokeDelegate<TContext> next;
        private UnZip[] unZipArray;
        private string accessControlAllowOrigin;
        public UnZipMiddleware(InvokeDelegate<TContext> next, UnZipConfig config)
        {
            this.unZipArray = config.unZipArray;
            UnZipServer.InitDefaultContentTypes();
            this.accessControlAllowOrigin = config.accessControlAllowOrigin;
            if (config.defaultUrl == null)
            {
                this.defaultUrl = "/";
            }
            else
            {
                this.defaultUrl = config.defaultUrl;
            }
            foreach(var unZip in unZipArray)
            {
                UnZipServer.GetAllStream(unZip.zipFileStream, unZip.requestPrefix, unZip.password);
            }
            this.next = next;
        }
        public virtual string GetRequestPath(TContext context)
        {
            throw new NotImplementedException();
        }
        public virtual void AddOrUpdateHeader(TContext context,string key,string[] value)
        {
            throw new NotImplementedException();
        }
        public virtual void SetStatusCode(TContext context,int statusCode)
        {
            throw new NotImplementedException();
        }
        public virtual Stream GetResponseStream(TContext context)
        {
            throw new NotImplementedException();
        }
        public async Task Invoke(TContext context)
        {
            string requestPath= GetRequestPath(context);
            if (requestPath.StartsWith("/"))
            {
                if (requestPath.Length == 1)
                {
                    requestPath = defaultUrl;
                }
                var response = UnZipServer.GetResponse(requestPath);
                if (response.body != null)
                {
                    
                    if (accessControlAllowOrigin != null)
                    {
                        AddOrUpdateHeader(context, "Access-Control-Allow-Origin", new string[] { accessControlAllowOrigin });
                    }
                    foreach (var header in response.headers)
                    {
                        AddOrUpdateHeader(context, header.Key, header.Value);
                    }
                    SetStatusCode(context,response.statusCode);
                    Stream body = GetResponseStream(context);
                    response.body.Seek(0, SeekOrigin.Begin);
                    await response.body.CopyToAsync(body);
                }
                else
                {
                    await next(context);
                }
            }
            else
            {
                await next(context);
            }
        }
    }
}
